package com.betterjr.modules.application.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.betterjr.common.service.BaseService;
import com.betterjr.common.utils.BTAssert;
import com.betterjr.common.utils.CacheUtils;
import com.betterjr.common.utils.Collections3;
import com.betterjr.common.utils.QueryTermBuilder;
import com.betterjr.common.utils.UserUtils;
import com.betterjr.modules.application.dao.ApplicationMapper;
import com.betterjr.modules.application.data.ApplicationConstantCollections;
import com.betterjr.modules.application.data.ApplicationGroupConstantCollections;
import com.betterjr.modules.application.data.ApplicationOperorgConstantCollections;
import com.betterjr.modules.application.entity.Application;

/**
 * 
 * @ClassName: ApplicationService 
 * @Description: 应用服务
 * @author xuyp
 * @date 2017年11月17日 下午6:06:36 
 *
 */
@Service
public class ApplicationService extends BaseService<ApplicationMapper, Application> {

    @Autowired
    private ApplicationOperorgService operOrgService;

    @Autowired
    private AmsMenuInfoService menuService;

    /**
     * 此方法用于查询前端根据 分组或者类型查询应用信息
     * @Title: queryEffectiveApplicationsByApplicationType 
     * @Description: 根据应用类型或者应用分类查询应用列表 ( 1 待发布 2 正常 3下架 4 删除)
     * @param anApplcationTypeId  应用类型id
     * @param anApplcationGroupId  应用分组id
     * @return TODO(说明)
     * @throws 
     * @author xuyp
     * @date 2017年11月15日 上午11:02:48
     */

    @SuppressWarnings("unchecked")
    public List<Application> queryEffectiveApplicationsByApplicationType(Long anApplcationTypeId,
            Long anApplcationGroupId, String anBusinStatus) {

        Map<String, Object> map = QueryTermBuilder.newInstance().put("businStatus", anBusinStatus)
                .put("operOrg", UserUtils.getOperatorInfo().getOperOrg()).build();

        if (StringUtils.isBlank(anBusinStatus)) {
            map.put("businStatus", ApplicationConstantCollections.APPLICATION_BUSINSTATUS_EFFECTIVE_STRING_ARRAY);
        } else {
            if (anBusinStatus.contains(ApplicationGroupConstantCollections.SYSTEM_VALUE_FILE_SEPARATOR)) {
                map.put("businStatus",
                        anBusinStatus.split(ApplicationGroupConstantCollections.SYSTEM_VALUE_FILE_SEPARATOR));
            }
        }

        if (null != anApplcationTypeId) {
            map.put("applicationTypeId", anApplcationTypeId);
        }

        if (null != anApplcationGroupId) {
            map.put("applicationGroupId", anApplcationGroupId);
        }

        return this.selectByProperty(map, "id Desc");
    }

    /**
     * 
     * @Title: queryApplicationsByMap 
     * @Description: 平台查询应用表列表信息 
     * @param anMap
     * @param anApplicationName
     * @return 平台admin查询应用表列表信息 
     * @throws 
     * @author xuyp
     * @date 2017年12月12日 下午3:40:44
     *  "applicationTypeId", "applicationGroupId", "ruleList",
                "applicationName", "businStatus" 
     */
    @SuppressWarnings("unchecked")
    public List<Application> queryApplicationsByMap(Map<String, Object> anMap) {

        BTAssert.notNull(anMap, "数据为空,操作失败");
        anMap = Collections3.filterMapEmptyObject(anMap);
        anMap = Collections3.filterMap(anMap, new String[] { "applicationTypeId", "applicationGroupId", "ruleList",
                "applicationName", "businStatus" });
        anMap = Collections3.fuzzyMap(anMap, new String[] { "ruleList", "applicationName" });

        // 处理businStatus 格式为 1,2 的格式
        if (anMap.containsKey("businStatus")) {
            if (StringUtils.isNoneBlank(anMap.get("businStatus").toString())) {
                if (anMap.get("businStatus").toString()
                        .contains(ApplicationGroupConstantCollections.SYSTEM_VALUE_FILE_SEPARATOR)) {
                    anMap.put("businStatus", anMap.get("businStatus").toString()
                            .split(ApplicationGroupConstantCollections.SYSTEM_VALUE_FILE_SEPARATOR));
                }
            }
        }

        anMap.put("operOrg", UserUtils.getOperatorInfo().getOperOrg());

        return this.selectByProperty(anMap, "id Desc");

    }

    /**
     * 新增或者保存应用信息
     * @Title: saveOrUpdateApplication 
     * @Description: 新增或者保存应用信息 
     * @param anApplication
     * @return TODO(说明)
     * @throws 
     * @author xuyp
     * @date 2017年11月15日 下午2:55:59
     * 
     * id
     * applicationName
     * description
     * applicationIcon
     * applicationColor
     * applicationTypeId
     * applicationGroupId
     * ruleList
     * applicationShowType
     * showUrl
     */
    public Application saveOrUpdateApplication(Application anApplication) {

        BTAssert.notNull(anApplication, "数据为空,操作失败");

        if (null == anApplication.getId()) {
            // 新增应用
            anApplication.saveModifyValue(UserUtils.getOperatorInfo(), "1");
            this.insertSelective(anApplication);
            // 插入应用机构表记录信息
            operOrgService.saveAddByApplication(anApplication,
                    ApplicationOperorgConstantCollections.APPLICATIONOPERORG_BUSINSTATUS_NOEFFECTIVE);

        } else {
            // 修改应用
            Application application = this.selectByPrimaryKey(anApplication.getId());
            BTAssert.notNull(application, "数据为空,操作失败");
            anApplication.saveModifyValue(UserUtils.getOperatorInfo(), "2");

            anApplication.setBusinStatus(application.getBusinStatus());
            checkApplicationAux(anApplication, application.getOperOrg());

            // 判断是否更新菜单表中的角色
            if (!application.getRuleList().equals(anApplication.getRuleList())) {
                menuService.saveUpdateRuleListByApplicaitonId(anApplication.getId(), anApplication.getRuleList());
            }

            this.updateByPrimaryKeySelective(anApplication);
            // 更新应用机构表记录信息
            if (!anApplication.getApplicationGroupId().equals(application.getApplicationGroupId())
                    || !anApplication.getApplicationTypeId().equals(application.getApplicationTypeId())) {
                operOrgService.saveModifyByApplication(anApplication);
            }
        }

        return anApplication;
    }

    /**
     * 
     * @Title: saveModifyApplicationBusinStatus 
     * @Description: 修改应用状态    上架 下架 卸载等信息 
     * @param anApplicationId
     * @param anBusinStatus
     * @return TODO(说明)
     * @throws 
     * @author xuyp
     * @date 2017年11月16日 上午9:52:38
     */
    public Application saveModifyApplicationBusinStatus(Long anApplicationId, String anBusinStatus) {

        BTAssert.notNull(anApplicationId, "数据为空,操作失败");
        Application application = this.selectByPrimaryKey(anApplicationId);
        BTAssert.notNull(application, "数据为空,操作失败");
        checkApplicationAux(application, UserUtils.getOperatorInfo().getOperOrg());
        application.setBusinStatus(anBusinStatus);
        this.updateByPrimaryKeySelective(application);

        // 修改应用上架下架卸载同步操作

        operOrgService.saveApplicationBusinStatusSynchronized(application);
        return application;
    }

    /**
     * 
     * @Title: findApplicationNameById 
     * @Description: 根据应用id查询应用名称
     * @param anApplicationId
     * @return TODO(说明)
     * @throws 
     * @author xuyp
     * @date 2017年11月16日 下午1:42:54
     */
    public String findApplicationNameById(Long anApplicationId) {

        String applicationName = "";
        try {
            Object object = CacheUtils
                    .get(ApplicationConstantCollections.APPLIATION_REDIS_APPLICAITONNAME_KEY + anApplicationId);
            if (object != null) {
                applicationName = object.toString();
            }
        }
        catch (Exception e) {
            logger.info("redis exception" + e.getMessage());
        }

        if (StringUtils.isBlank(applicationName)) {
            Application application = this.selectByPrimaryKey(anApplicationId);

            applicationName = application.getApplicationName();
            try {
                CacheUtils.put(ApplicationConstantCollections.APPLIATION_REDIS_APPLICAITONNAME_KEY + anApplicationId,
                        applicationName);
            }
            catch (Exception e) {
                logger.info("redis exception" + e.getMessage());
            }
        }

        return applicationName;

    }

    /**
     * 
     * @Title: queryEffectiveApplicaitonsByIds 
     * @Description: 根据应用id集合查询所有的生效的应用 
     * @param anApplicationIds
     * @return  List<Application> 
     * @throws 
     * @author xuyp
     * @date 2017年11月20日 下午2:56:34
     */
    @SuppressWarnings("unchecked")
    public List<Application> queryEffectiveApplicaitonsByIds(String anApplicationIds) {

        if (StringUtils.isBlank(anApplicationIds)) {
            return new ArrayList<Application>();
        }

        List<Long> longList = createLongListByString(anApplicationIds);
        if (Collections3.isEmpty(longList)) {
            return new ArrayList<Application>();
        }

        Map<String, Object> map = QueryTermBuilder.newInstance()
                .put("businStatus", ApplicationConstantCollections.APPLICATION_BUSINSTATUS_PUBLISHING)
                .put("id", longList).build();

        return this.selectByProperty(map, "id desc");
    }

    /**
     * 
     * @Title: createLongListByString 
     * @Description: 将ids转换成集合 
     * @param anApplicationIds
     * @return TODO(说明)
     * @throws 
     * @author xuyp
     * @date 2017年11月20日 下午3:04:47
     */
    private List<Long> createLongListByString(String anApplicationIds) {

        List<Long> longList = new ArrayList<>();
        if (StringUtils.isNoneBlank(anApplicationIds)) {

            List<String> list = Arrays
                    .asList(anApplicationIds.split(ApplicationGroupConstantCollections.SYSTEM_VALUE_FILE_SEPARATOR));
            for (String str : list) {
                try {
                    longList.add(Long.parseLong(str));
                }
                catch (Exception e) {

                }
            }

        }
        return longList;
    }

    /**
     * 
     * @Title: checkApplicationAux 
     * @Description: 校验插入的对象是否符合条件 
     * @param anApplication
     * @param anOperOrg 数据库记录已经存放的操作机构
     * @throws 
     * @author xuyp
     * @date 2017年11月15日 下午3:37:36
     */
    private void checkApplicationAux(Application anApplication, String anOperOrg) {

        BTAssert.isTrue(
                !ApplicationConstantCollections.APPLICATION_BUSINSTATUS_DELETEED.equals(anApplication.getBusinStatus()),
                "当前应用已经删除,操作失败");

        BTAssert.isTrue(anApplication.getOperOrg().equals(anOperOrg), "你没有当前操作权限,操作失败");

    }

}
